package pers.liyan.shi.springcloud.controller;

import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.*;
import pers.liyan.shi.springcloud.domain.Dept;
import pers.liyan.shi.springcloud.service.IDeptService;

import java.util.List;

@RestController
@RequestMapping("/dept")
public class DeptController {

    private final IDeptService deptService;

    /**
     * Always use constructor based dependency injection in your beans.
     * Always use assertions for mandatory dependencies
     * 使用构造器注入, 使用断言
     */
    @Autowired
    public DeptController(IDeptService deptService) {
        Assert.notNull(deptService, "deptService cannot be null");
        this.deptService = deptService;
    }

    /**
     * 查询所有部门信息
     * @return
     */
    @ApiOperation(value = "查询所有部门信息", notes = "获取所有部门的详细信息,包含部门编号,部门名称,数据源")
    @GetMapping("/")
    // @HystrixCommand
    public List<Dept> findAll() {
        return deptService.findAll();
    }

    /**
     * 方法出现异常后会调用{@code fallbackMethod}指定的方法, 服务熔断
     * {@code paramType = "path"} 表示参数为url参数
     * @param deptNo 部门编号
     * @return
     */
    @ApiOperation(value = "通过部门编号查询部门信息", notes = "通过主键查询部门的信息")
    @ApiImplicitParam(name = "deptNo", value = "部门编号", dataType = "Long", paramType = "path")
    @HystrixCommand(fallbackMethod = "findByDeptNoFallBack")
    @GetMapping("/{deptNo}")
    public Dept findByDeptNo(@PathVariable Long deptNo) {
        //模拟发生异常的情况
        if(deptNo < 1){
            throw new RuntimeException("部门编号不合法");
        }
        return deptService.findByNo(deptNo);
    }

    /**
     * updateDept fallback方法, 必须与{@link #findByDeptNo(Long)}方法参数列表一致
     */
    public Dept findByDeptNoFallBack(Long deptNo){
        return new Dept().setDeptName("查询异常 deptNo[" + deptNo + "]");
    }


    @ApiOperation(value = "添加部门", notes = "新增部门,部门编号和数据源信息自动获取")
    @ApiImplicitParam(name = "dept", value = "部门信息, 不需要数据库名和编号", dataType = "Dept", paramType = "body")
    @PostMapping("/")
    public Dept addDept(@RequestBody Dept dept) {
        this.deptService.addDept(dept);
        return dept;
    }

    /**
     * 添加 {@code @RequestBody} 注解后, swagger中才能正常识别参数类型为 body, 或者使用 {@code paramType = "body"}
     *
     */
    @PutMapping("/")
    @ApiOperation(value = "更新部门信息")
    @ApiImplicitParam(name = "dept", value = "部门信息, 不需要数据库名", dataType = "Dept", paramType = "body")
    public Dept updateDept(@RequestBody Dept dept) {
        this.deptService.updateByNo(dept);
        return dept;
    }

    @ApiOperation(value = "删除部门信息")
    @ApiImplicitParam(name = "deptNo", value = "部门编号", dataType = "Long", paramType = "path")
    @DeleteMapping("/{deptNo}")
    public int deleteByNo(@PathVariable Long deptNo) {
        return this.deptService.deleteByNo(deptNo);
    }

}
